<template>
  <div class="analysis-style-layout four-scroll-y">
    <!-- 节点属性编码 -->
    <div class="node-style-layout-header">
      <span>节点属性编码</span>
      <a-icon
        :type="nodeStyleFoldClose ? 'up' : 'down'"
        @click="nodeStyleFoldClose = !nodeStyleFoldClose"
      />
    </div>
    <div
      class="node-style-content"
      :class="{ 'close-fold': nodeStyleFoldClose }"
    >
      <!-- 节点类型 -->
      <div class="node-style-items">
        <div class="node-style-title">节点类型</div>
        <div class="node-style-info">
          <div class="item-main-information">
            <a-select
              v-model="selectNodeTypeList"
              placeholder="请选择..."
              mode="multiple"
              size="small"
              class="node-type-select"
            >
              <a-select-option
                v-for="(item, index) in allNodeTypeList"
                :key="index"
                :value="item.id"
              >
                {{ item.label }}
              </a-select-option>
            </a-select>
          </div>
        </div>
      </div>
      <!-- 属性着色 -->
      <div class="node-style-items">
        <div class="node-style-title">属性</div>
        <div class="node-style-info">
          <div class="item-main-information">
            <a-select
              v-model="selectedAttribute"
              placeholder="请选择..."
              size="small"
              class="item-select"
            >
              <a-select-option
                v-for="(item, index) in currentItemArray"
                :key="index"
                :value="item"
              >
                {{ item }}
              </a-select-option>
            </a-select>
          </div>
        </div>
      </div>
      <!-- 编码方式 -->
      <div class="node-style-items">
        <div class="node-style-title">编码方式</div>
        <div class="node-style-info">
          <div class="item-main-information">
            <a-radio-group v-model="setEncodingType">
              <a-radio-button button-style="solid" :value="1"
                >颜色
              </a-radio-button>
              <a-radio-button
                button-style="solid"
                :value="2"
                :disabled="!numberAttrShow"
                >大小
              </a-radio-button>
            </a-radio-group>
          </div>
        </div>
      </div>
      <!--  颜色设置 -->
      <div v-if="setEncodingType === 1" class="node-style-items">
        <div class="node-style-title">
          <a-radio-group
            v-if="numberAttrShow"
            v-model="setColorValueType"
            class="randio-group-title"
          >
            <a-radio :value="1">离散</a-radio>
            <a-radio :value="2">连续</a-radio>
          </a-radio-group>
        </div>
        <div class="node-style-info">
          <div class="sort-setting-information">
            <div>
              <!-- 离散颜色-->
              <div
                class="item-additional-information"
                @click="() => (setColorValueType = 1)"
              >
                <a-spin
                  :spinning="attributeClassificationColorLoading"
                  :delay="500"
                  size="small"
                  tip="loading..."
                >
                  <div
                    v-if="attributeColorContentList.length !== 0"
                    class="additional-information-header"
                  >
                    <span class="header-attribute">值</span>
                    <span class="header-proportion">占比</span>
                    <span class="header-count">数量</span>
                  </div>
                  <div class="additional-information-items four-scroll-y">
                    <div
                      v-for="(item, index) in attributeColorContentList"
                      :key="index"
                      class="additional-information-content"
                    >
                      <!-- 值 -->
                      <div
                        class="content-attribute text-overflow-ellipsis"
                        :title="item.value"
                      >
                        <span
                          :style="{ 'background-color': item.color }"
                        ></span>
                        {{ item.value }}
                      </div>
                      <!-- 占比 -->
                      <span
                        class="content-proportion"
                        :title="(item.proportion * 100).toFixed(2) + '%'"
                      >
                        {{ (item.proportion * 100).toFixed(2) }}%
                      </span>
                      <!-- 数量 -->
                      <div
                        class="content-count text-overflow-ellipsis"
                        :title="item.count"
                      >
                        {{ item.count }}
                      </div>
                    </div>
                  </div>
                  <div
                    v-if="attributeColorContentList.length === 0"
                    class="graph-attribute-info-empty"
                  >
                    {{
                      attributeClassificationColorLoading
                        ? ''
                        : '-- 属性信息为空 --'
                    }}
                  </div>
                </a-spin>
              </div>
              <!-- 连续颜色-->
              <div
                v-if="numberAttrShow"
                class="select-set-color size-color-content"
              >
                <div
                  class="gradient-bar"
                  @click="() => (setColorValueType = 2)"
                >
                  <span
                    v-for="(color, index) in initGradientColor"
                    :key="index"
                    class="gradient-bar-item"
                    :style="{ 'background-color': color }"
                  ></span>
                </div>
                <a-popover
                  placement="left"
                  trigger="click"
                  :overlay-class-name="'popover-color-set'"
                  :visible="showColorPicker"
                  @visibleChange="visibleChange"
                >
                  <span
                    :style="{ cursor: 'pointer' }"
                    class="select-color-popover"
                  >
                    <a-icon-font type="icongengduocaozuo" />
                  </span>
                  <compact
                    slot="content"
                    v-model="currentColor"
                    :palette="systemDefaultColor"
                  />
                </a-popover>
              </div>
            </div>
          </div>
        </div>
      </div>
      <!-- 大小设置-->
      <div v-else class="node-style-items">
        <div class="node-style-title">区间设置</div>
        <div class="node-style-info">
          <div class="sort-setting-information">
            <div
              :style="{
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'space-between',
              }"
            >
              <a-input-number
                v-model="minSetValue"
                size="small"
                :min="1"
                :max="100"
                class="size-value-input"
              />
              <div
                :style="{ width: '10%', height: '2px', background: '#a2a2a5' }"
              />
              <a-input-number
                v-model="maxSetValue"
                size="small"
                :min="1"
                :max="100"
                class="size-value-input"
              />
            </div>
          </div>
        </div>
      </div>
      <!--运行按钮-->
      <div class="node-style-items">
        <div class="node-style-title" />
        <div class="node-style-info">
          <a-button
            size="small"
            class="run-button"
            @click="colorOrSizeRunDebounce"
            >运行
          </a-button>
        </div>
      </div>
    </div>

    <!-- 布局设置 -->
    <div class="node-style-layout-header node-layout-header">
      <span>布局设置</span>
      <a-icon
        :type="nodeLayoutFoldClose ? 'up' : 'down'"
        @click="nodeLayoutFoldClose = !nodeLayoutFoldClose"
      />
    </div>
    <div
      class="node-layout-content"
      :class="{ 'close-fold': nodeLayoutFoldClose }"
    >
      <!-- 布局算法类 -->
      <div class="node-layout-items">
        <div class="node-layout-title">布局算法</div>
        <div class="node-layout-info">
          <div class="item-main-information">
            <a-select
              v-model="currentLayoutClass"
              default-value="Force Layout"
              size="small"
              class="item-select-no-button"
              @change="layoutClassChange"
            >
              <a-select-option
                v-for="(item, index) in layoutClassArray"
                :key="index"
                :value="item.classId"
              >
                {{ item.className }}
              </a-select-option>
            </a-select>
          </div>
        </div>
      </div>
      <!--  layout 布局 item -->
      <div class="layout-items-array">
        <div
          v-for="(layout, index) in layoutArray[currentLayoutClass]"
          :key="index"
          class="layout-item"
          :class="{
            'active-layout-item': currentApplicationLayoutId === layout.id,
          }"
          @click="useCurrentLayout(layout)"
        >
          <div class="layout-icon">
            <a-popover
              placement="top"
              :destroy-tooltip-on-hide="true"
              :overlay-class-name="'popover-custom-name'"
              :mouse-leave-delay="0"
              :mouse-enter-delay="0.5"
              :overlay-style="{
                width: '176px',
              }"
            >
              <template slot="content">
                <img
                  :src="publicPath + layout.popoverGif"
                  class="layout-img-popover"
                />
              </template>
              <img :src="publicPath + layout.imageSrc" class="layout-img" />
            </a-popover>
          </div>
          <div class="layout-text text-overflow-ellipsis">
            {{ layout.name }}
          </div>
        </div>
      </div>
      <!--  layout 参数配置 -->
      <div class="layout-setting-info">
        <div class="current-layout-parameter four-scroll-y">
          <template v-for="(parameter, index) in currentLayoutParameter.params">
            <div
              v-if="parameter.show"
              :key="index"
              class="layout-parameter-item"
              :class="{
                'active-parameter': showParameterIntroductionIndex === index,
              }"
              @click="viewCurrentParameter(index)"
            >
              <div
                class="parameter-name text-overflow-ellipsis"
                :title="parameter.paramName"
              >
                {{ parameter.paramName }}
              </div>
              <!-- 数值型 -->
              <template v-if="parameter.type === 'number'">
                <!-- 正常显示 -->
                <div
                  v-if="
                    parameter.isG6cfg
                      ? currentEditParams !== parameter.g6LayoutCfg
                      : currentEditParams !== parameter.key
                  "
                  class="parameter-value"
                  @dblclick="isEditingParamValue(parameter)"
                >
                  {{
                    parameter.value || parameter.value === 0
                      ? parameter.value
                      : 'null'
                  }}
                </div>
                <!-- 编辑状态 -->
                <a-input-number
                  v-else
                  v-model="parameter.value"
                  :max="parameter.max"
                  :min="parameter.min"
                  auto-focus
                  size="small"
                  class="parameter-value"
                  @blur="editParamsValueBlur"
                  @pressEnter="($event) => $event.target.blur()"
                />
              </template>
              <!-- 布尔型  -->
              <a-checkbox
                v-if="parameter.type === 'boolean'"
                v-model="parameter.value"
                size="small"
                class="parameter-value"
              />
              <!-- string -->
              <template v-if="parameter.type === 'string'">
                <!-- 正常显示 -->
                <div
                  v-if="
                    parameter.isG6cfg
                      ? currentEditParams !== parameter.g6LayoutCfg
                      : currentEditParams !== parameter.key
                  "
                  class="parameter-value"
                  @dblclick="isEditingParamValue(parameter)"
                >
                  {{ parameter.value ? parameter.value : 'null' }}
                </div>
                <!-- 编辑状态 -->
                <a-input
                  v-else
                  v-model="parameter.value"
                  auto-focus
                  size="small"
                  class="parameter-value"
                  @blur="editParamsValueBlur"
                  @pressEnter="($event) => $event.target.blur()"
                />
              </template>
            </div>
          </template>
          <div
            v-if="currentLayoutParameter.params.length === 0"
            class="no-params-setting"
          >
            -- 无可配置的参数 --
          </div>
        </div>
        <!-- 参数项详情 -->
        <div class="parameter-introduction four-scroll-y">
          <div
            class="introduction-title text-overflow-ellipsis"
            :title="parameterIntroductionInfo.paramName"
          >
            {{ parameterIntroductionInfo.paramName }}:
          </div>
          <div class="introduction-text">
            <span>{{ parameterIntroductionInfo.introduction }}</span>
          </div>
        </div>
      </div>
      <!-- run -->
      <div class="layout-run">
        <a-button
          size="small"
          class="run-button"
          @click="applyCurrentLayoutDebounce"
          >运行
        </a-button>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { debounce } from 'lodash'
import { Compact } from 'vue-color'
import { Component, Emit, Vue, Watch } from 'vue-property-decorator'
import {
  CIRCULAR,
  CIRCULAR_ARC,
  ROTATING,
  initGradientColor,
  layoutArray,
  layoutParameters,
  systemDefaultColor,
} from '@/components/right-drawer/style-layout-config/style-layout'
import GraphAnalysis from '@/store/modules/graphanalysis'
import { getLightColorFromBasedColor } from '@/components/util/graph-util'
import {
  queryAttributeStyle,
  queryAvailableAttributes,
} from '@/api/graph-analysis'
import {
  ICategories,
  IAttributeColorContentListItem,
} from '@/components/right-drawer/style-layout-config/style-layout-interface'
import { publicPath } from '@/api/constants'

@Component({
  components: {
    Compact,
  },
})
export default class StyleLayout extends Vue {
  private nodeStyleFoldClose: boolean = false // node style fold
  private nodeLayoutFoldClose: boolean = false // layout fold
  // 节点类型 categories
  private allNodeTypeList: ICategories[] = [] // 节点类型
  private selectNodeTypeList: any[] = [] // 已经选择的节点类型
  // 属性着色
  private currentItemArray: string[] = [] // 属性着色可供选择的属性
  private selectedAttribute: string | null = null // 当前选择的属性
  private attributeClassificationColorLoading: boolean = false // 属性着色 loading
  public attributeColorContentList: IAttributeColorContentListItem[] = [] // 属性着色 detail， 每个属性值所占比例
  // 排序设置
  private sortAttributes: string[] = [] // 排列设置可供选择的属性
  private nodeSortList: any[] = [] // 根据属性值排序好的节点
  private setEncodingType: number = 1 // size / color
  private setColorValueType: number = 1 // 离散 / 连续
  private minSetValue: number = 10 // min set value
  private maxSetValue: number = 40 // max set value
  public currentColor: any = '#7751ff' // 当前基础色
  public systemDefaultColor: string[] = systemDefaultColor // 系统颜色： 颜色排序

  public showColorPicker: boolean = false // 颜色选择器 popover
  public visibleChange(value: boolean) {
    this.showColorPicker = value
  }

  private publicPath = publicPath

  // 颜色排序的色阶
  public initGradientColor: string[] = initGradientColor //
  @Watch('currentColor')
  public watchCurrentColor(value: any) {
    this.initGradientColor = []
    for (let i = 2; i < 10; i += 1) {
      this.initGradientColor.push(
        getLightColorFromBasedColor(value.hex, i / 10)
      )
    } // 根据这个颜色直做是个等级
    this.showColorPicker = false
  }

  public created() {}

  public mounted() {}

  public beforeDestroy() {}

  // 当前graphId
  public get graphId() {
    return GraphAnalysis.activeTabId
  }

  @Watch('graphId')
  public graphIdChange() {}

  // 当前图数据 节点分类 categories
  public get categories() {
    return GraphAnalysis.categories
  }

  // 切换graph 分类信息变化
  @Watch('categories')
  public categoriesChange() {
    this.updateNodeType()
  }

  /**
   * 更新节点类型，默认选择所有类型
   */
  public updateNodeType() {
    this.allNodeTypeList = this.categories
    this.selectNodeTypeList = this.categories.map(
      (categorize: any) => categorize.id
    )
  }

  // 节点类型信息变化， 更新属性设置， 排序设置的 可选项及选择项
  @Watch('selectNodeTypeList')
  public nodeAttributeChange() {
    this.currentItemArray = []
    this.selectedAttribute = null
    this.sortAttributes = []
    if (this.selectNodeTypeList.length === 0) {
      return
    } // 没有分类信息
    this.queryNodeTypeBasedAttribute()
  }

  /**
   * 请求属性列表,  属性着色 / 排序设置
   */
  public queryNodeTypeBasedAttribute() {
    const data: any = {
      projectId: GraphAnalysis.projectId,
      graphId: GraphAnalysis.activeTabId,
      categoryIds: this.selectNodeTypeList,
    }
    queryAvailableAttributes({ data }).then((response: any) => {
      if (response.data.code === 100) {
        const { numAttr, shareAttr } = response.data.result
        this.currentItemArray = shareAttr
        ;[this.selectedAttribute] = shareAttr
        GraphAnalysis.setShareAttr(shareAttr)
        this.sortAttributes = numAttr
      }
    })
  }

  /**
   * 属性着色 属性改变
   */
  @Watch('selectedAttribute')
  public selectedAttributeChange(newValue: string) {
    if (!newValue) {
      this.attributeColorContentList = []
      return
    }
    const data: any = {
      projectId: GraphAnalysis.projectId,
      graphId: GraphAnalysis.activeTabId,
      categoryIds: this.selectNodeTypeList,
      attr: newValue,
      mode: 'group',
    }
    this.attributeClassificationColorLoading = true
    queryAttributeStyle({ data })
      .then((response: any) => {
        if (response.data.code === 100) {
          this.attributeColorContentList = response.data.result
        }
      })
      .finally(() => {
        this.attributeClassificationColorLoading = false
      })

    this.findSortNodes(newValue)
  }

  /**
   * 排序设置 属性改变
   */
  public findSortNodes(newValue: string) {
    if (
      !newValue || // 如果为null
      !this.sortAttributes.includes(newValue)
    ) {
      // 判断一下是否为可以排序的属性
      this.nodeSortList = []

      // 跳转回颜色编码方式
      this.setColorValueType = 1
      this.setEncodingType = 1
      return
    }

    const data: any = {
      projectId: GraphAnalysis.projectId,
      graphId: GraphAnalysis.activeTabId,
      categoryIds: this.selectNodeTypeList,
      attr: newValue,
      mode: 'sort',
    }

    queryAttributeStyle({ data }).then((response: any) => {
      if (response.data.code === 100) {
        this.nodeSortList = response.data.result
      }
    })
  }

  // 如果切换的属性为数值属性，可以显示更多的设置：连续型色彩、大小排序
  public get numberAttrShow() {
    return this.nodeSortList !== null && this.nodeSortList.length > 0
  }

  // 布局分类
  private layoutClassArray: any[] = [
    { className: '力导布局', classId: 1 },
    { className: '环形布局', classId: 2 },
    { className: '辐射布局', classId: 3 },
    { className: '随机布局', classId: 4 },
    { className: '弧线布局', classId: 5 },
    { className: '工具类', classId: 6 },
  ]
  // 所有布局
  private layoutArray: { [key: string]: any } = layoutArray
  // 当前 graph 应用的 layout
  private currentUseLayout: { classId: number; layoutId: number } = {
    classId: 1,
    layoutId: 1,
  }
  // 当前选择的布局分类
  private currentLayoutClass: number = 1
  // 当前选择的布局 Id
  public currentApplicationLayoutId: any = 1
  public currentLayoutParameter: any =
    layoutParameters[this.currentApplicationLayoutId] // 当前 选择的布局 信息，
  private showParameterIntroductionIndex: number = 0 // 当前要显示的参数项序号
  public get parameterIntroductionInfo() {
    if (this.currentLayoutParameter?.params?.length > 0) {
      return this.currentLayoutParameter.params[
        this.showParameterIntroductionIndex
      ]
    }
    return { paramName: '请选择参数', introduction: '-- 空 --' }
  }

  // G6LayoutCfg
  private currentEditParams: any = null // 当前编辑的参数

  /**
   * 布局类切换
   * classId classLayoutId
   */
  public layoutClassChange(classId: any) {
    let selectLayoutId: number = this.layoutArray[classId][0].id // 默认选择第一个布局
    if (this.currentUseLayout.classId === classId) {
      selectLayoutId = this.currentUseLayout.layoutId
    }
    this.currentApplicationLayoutId = selectLayoutId
    this.currentLayoutParameter =
      layoutParameters[this.currentApplicationLayoutId]
    this.showParameterIntroductionIndex = 0
  }

  /**
   * 点击选择 layout
   * @param layout
   */
  public useCurrentLayout(layout: any) {
    this.currentApplicationLayoutId = layout.id
    this.currentLayoutParameter =
      layoutParameters[this.currentApplicationLayoutId]
    this.showParameterIntroductionIndex = 0
  }

  /**
   * 点击选择参数项 查看参数介绍
   * @param index
   */
  public viewCurrentParameter(index: number) {
    this.showParameterIntroductionIndex = index
  }

  /**
   * 编辑参数
   * @param parameter
   */
  public isEditingParamValue(parameter: any) {
    if (parameter.isG6cfg) {
      this.currentEditParams = parameter.g6LayoutCfg
    } else {
      this.currentEditParams = parameter.key
    }
  }

  /**
   * 编辑参数值失去焦点
   */
  public editParamsValueBlur() {
    this.currentEditParams = null
  }

  private applyCurrentLayoutDebounce = debounce(
    () => this.applyCurrentLayout(),
    100
  )

  /**
   * 运行
   * introduce: type -->
   * 'layout-run'-布局运行
   * 'color-run'-着色运行
   * 'sort-run'-排序运行
   */
  @Emit('style-layout-run')
  public applyCurrentLayout() {
    this.currentUseLayout.classId = this.currentLayoutClass
    this.currentUseLayout.layoutId = this.currentApplicationLayoutId
    const cfg: any = {
      // layoutId: this.currentUseLayout.layoutId,
      type: this.currentLayoutParameter.g6LayoutType,
    }
    const notG6Cfg: any = {} // 非G6参数
    // 通用的配置，G6参数， 有些是g6， 将参数分开,（是否是 g6 参数）
    this.currentLayoutParameter.params?.forEach((parameter: any) => {
      if (parameter.isG6cfg) {
        cfg[parameter.g6LayoutCfg] =
          parameter.type === 'number'
            ? Number(parameter.value)
            : parameter.value
      } else {
        notG6Cfg[parameter.key] =
          parameter.type === 'number'
            ? Number(parameter.value)
            : parameter.value
      }
    })
    // 环形布局，定义半径
    // 半径为空的时候
    // if (cfg.type === CIRCULAR && notG6Cfg.isAutoRadius) {
    if ((cfg.type === CIRCULAR || cfg.type === CIRCULAR_ARC) && !cfg.radius) {
      const { width, height } = GraphAnalysis.graphAnalysisRootSize
      const AutoRadius: number = Math.min(width, height) / 3
      cfg.radius = Number(AutoRadius)
      delete cfg.autoRadius
    }
    // 旋转
    if (cfg.type === ROTATING) {
      Object.assign(cfg, notG6Cfg)
    }
    // 是否支持节点防止重叠
    return {
      type: 'layout-run',
      info: cfg,
    }
  }

  /**
   * 属性着色
   */
  public attributeColorRun() {
    if (
      this.setColorValueType === 1 &&
      this.attributeColorContentList.length > 0
    ) {
      this.attributeColorRunEmit()
    } else if (this.setColorValueType === 2 && this.nodeSortList.length > 0) {
      this.attributeColorRunEmit()
    } else {
      this.$message.warning('请选择可着色的属性/没有可着色的属性！')
    }
  }

  @Emit('style-layout-run')
  public attributeColorRunEmit() {
    if (this.setColorValueType === 1) {
      return {
        type: 'attribute-color-run',
        info: this.attributeColorContentList,
      }
    }

    return {
      type: 'sort-run',
      info: {
        nodesWeight: this.nodeSortList,
        currentColor:
          typeof this.currentColor === 'string'
            ? this.currentColor
            : this.currentColor.hex,
      },
      sizeOrColor: this.setEncodingType,
    }
  }

  /**
   * 排序设置
   */
  public attributeSizeRun() {
    if (this.nodeSortList.length > 0) {
      this.attributeSizeRunEmit()
    } else {
      this.$message.warning('请选择可排序的属性/没有可排序的属性！')
    }
  }

  @Emit('style-layout-run')
  public attributeSizeRunEmit() {
    const info: any = {
      nodesWeight: this.nodeSortList,
      minSetValue: this.minSetValue,
      maxSetValue: this.maxSetValue,
    }
    return {
      type: 'sort-run',
      sizeOrColor: this.setEncodingType,
      info,
    }
  }

  /**
   * 颜色或者大小运行
   */
  private colorOrSizeRunDebounce = debounce(() => this.colorOrSizeRun(), 100)

  public colorOrSizeRun() {
    if (this.setEncodingType === 1) {
      this.attributeColorRun()
    } else {
      this.attributeSizeRun()
    }
  }
}
</script>

<style scoped lang="less">
@import '@/styles/scroll-bar';

.analysis-style-layout {
  background-color: #f8f7fd;
  height: calc(100% - 37px);
  overflow: hidden;
  overflow-y: auto;
  width: 100%;

  // header
  .node-style-layout-header {
    align-items: center;
    background-color: #f9f9fc;
    display: flex;
    font-size: 14px;
    height: 38px;
    justify-content: space-between;
    padding: 0 24px;
    user-select: none;

    > span {
      color: #5d637e;
      font-weight: 600;
      letter-spacing: 1px;
    }
  }

  // layout header
  .node-layout-header {
    border-top: 1px solid #e9e9e9;
  }

  // 节点样式 模块
  .node-style-content {
    height: auto;
    overflow: hidden;
    padding: 0 24px;

    .node-style-items {
      display: flex;
      margin-top: 15px;

      .node-style-title {
        color: #5d637e;
        font-size: 14px;
        font-weight: 400;
        letter-spacing: 1px;
        margin-right: 16px;
        text-align: right;
        user-select: none;
        width: 62px;

        // 单选框
        .randio-group-title {
          display: flex;
          flex-direction: column;
          height: 100%;
          justify-content: space-between;
          padding-top: 15px;
        }
      }

      .node-style-info {
        width: calc(100% - 78px);

        .item-main-information {
          align-items: center;
          display: flex;
          justify-content: space-between;
          width: 100%;

          .item-select {
            width: 100%;
          }

          .node-type-select {
            width: 100%;
          }
        }

        .run-button {
          margin-bottom: 10px;
          width: 52px;

          &:hover {
            background-color: #6973ff;
            color: #fff;
          }
        }

        // 配置详情
        .item-additional-information {
          background: #fff;
          border: 1px solid rgba(0, 0, 0, 0.07);
          color: #5d637e;
          font-size: 12px;
          font-weight: 400;
          letter-spacing: 1.12px;
          margin-top: 9px;
          padding: 12px 0 12px 12px;
          width: 100%;

          // 属性着色 表头
          .additional-information-header {
            display: flex;
            height: 28px;
            justify-content: space-between;
            line-height: 28px;

            span {
              display: inline-block;
              text-align: left;
            }

            .header-attribute {
              padding-left: 28px;
              width: 50%;
            }

            .header-proportion {
              width: 20%;
            }

            .header-count {
              width: 20%;
            }
          }

          // 属性着色 内容
          .additional-information-items {
            max-height: 112px;
            width: 100%;

            .additional-information-content {
              display: flex;
              height: 28px;
              justify-content: space-between;

              .content-attribute {
                line-height: 28px;
                text-align: left;
                user-select: none;
                width: 50%;

                span {
                  display: inline-block;
                  height: 16px;
                  margin-right: 12px;
                  vertical-align: middle;
                  width: 16px;
                }
              }

              .content-proportion {
                line-height: 28px;
                text-align: left;
                user-select: none;
                width: 20%;
              }

              .content-count {
                line-height: 28px;
                text-align: left;
                user-select: none;
                width: 20%;
              }
            }
          }

          .graph-attribute-info-empty {
            color: #5d637e;
            height: 140px;
            line-height: 140px;
            text-align: center;
            user-select: none;
          }
        }

        // 排序设置内容
        .sort-setting-information {
          font-size: 14px;
          width: 100%;
          // 排序设置
          .size-color-content {
            margin-top: 12px;
          }

          // 大小
          .select-set-size {
            .size-value-set {
              margin-top: 12px;
              min-width: 120px;

              > span {
                display: inline-block;
                user-select: none;
                width: 60px;
              }

              .size-value-input {
                margin-left: 12px;
                width: calc(100% - 72px);
              }
            }
          }

          // 颜色
          .select-set-color {
            align-items: center;
            display: flex;
            flex-wrap: wrap;
            justify-content: flex-start;
            width: 100%;

            .gradient-bar {
              height: 24px;
              width: calc(100% - 40px);

              .gradient-bar-item {
                display: inline-block;
                height: 24px;
                width: 12.5%;
              }
            }

            .select-color-popover {
              height: 24px;
              line-height: 24px;
              margin-left: 12px;
              text-align: center;
              width: 24px;

              &:hover {
                background-color: rgba(105, 115, 255, 0.1);
              }
            }
          }
        }
      }
    }
  }

  // 布局设置
  .node-layout-content {
    height: auto;
    overflow: hidden;
    padding: 0 24px;

    .node-layout-items {
      display: flex;
      margin-top: 20px;

      .node-layout-title {
        color: #5d637e;
        font-size: 14px;
        font-weight: 400;
        letter-spacing: 1px;
        margin-right: 16px;
        user-select: none;
        width: 62px;
      }

      .node-layout-info {
        width: calc(100% - 78px);

        .item-main-information {
          align-items: center;
          display: flex;
          justify-content: space-between;
          width: 100%;

          .item-select-no-button {
            width: 100%;
          }
        }
      }
    }

    // 布局列表
    .layout-items-array {
      display: flex;
      flex-wrap: wrap;
      justify-content: flex-start;
      margin: 20px -20px 16px 0;

      .layout-item {
        align-items: center;
        cursor: pointer;
        display: flex;
        flex-direction: column;
        justify-content: center;
        margin-right: 20px;
        width: 104px;

        //&:nth-child(3n+0) {
        //  margin-right: 0;
        //}

        .layout-icon {
          background: #fff;
          border-radius: 2px;
          height: 72px;
          width: 104px;

          .layout-img {
            height: 72px;
            width: 104px;
          }

          .layout-ali-icon {
            font-size: 60px;
          }
        }

        .layout-text {
          color: #5d637e;
          font-size: 12px;
          font-weight: 400;
          height: 20px;
          letter-spacing: 0.22px;
          line-height: 20px;
          margin-top: 8px;
          text-align: center;
          width: 100%;
        }
      }

      .active-layout-item {
        .layout-img {
          border: 1px solid #c5c9ff;
          border-radius: 4px;
        }
      }
    }

    // 布局参数
    .layout-setting-info {
      background: #fff;
      border: 1px solid rgba(0, 0, 0, 0.07);
      display: flex;
      font-size: 12px;
      overflow: hidden;
      padding: 6px 0;
      width: 100%;

      // 参数项
      .current-layout-parameter {
        border-right: 1px solid rgba(0, 0, 0, 0.07);
        margin-bottom: -100px; //关键
        max-height: 292px;
        padding-bottom: 100px;
        width: 58%;

        .layout-parameter-item {
          align-items: center;
          color: #5d637e;
          cursor: pointer;
          display: flex;
          height: 24px;
          justify-content: space-between;
          //margin: 6px 0;
          padding: 0 12px;

          &:hover {
            background-color: rgb(233, 236, 253);
          }

          .parameter-name {
            width: 100px;
          }

          .parameter-value {
            width: calc(100% - 100px);
          }
        }

        .active-parameter {
          background-color: rgb(233, 236, 253);
        }

        // 无参数
        .no-params-setting {
          color: #5d637e;
          height: 24px;
          text-align: center;
          user-select: none;
        }
      }

      // 参数解释
      .parameter-introduction {
        color: #222432;
        font-size: 12px;
        letter-spacing: 1px;
        margin-bottom: -100px; //关键
        max-height: 292px;
        padding: 0 12px 100px;
        user-select: none;
        width: 42%;

        .introduction-title {
          font-weight: bold;
          height: 24px;
          line-height: 24px;
        }

        .introduction-text {
          font-weight: 400;
          line-height: 24px;
        }
      }
    }

    .layout-run {
      display: flex;
      justify-content: flex-end;
      margin: 12px 0;

      .run-button {
        width: 52px;

        &:hover {
          background-color: #6973ff;
          color: #fff;
        }
      }
    }
  }

  // 折叠
  .close-fold {
    height: 0;
  }

  // 修改ant-design的radio-button的样式
  .ant-radio-button-wrapper {
    height: 24px;
    line-height: 22px;
    padding: 0 30px;
  }

  /deep/ .ant-radio-button-wrapper-checked {
    background-color: #5561ff;
    color: #fff;
  }
}

.text-overflow-ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

// 布局
.popover-custom-name {
  .ant-popover-content {
    .ant-popover-inner {
      box-shadow: 0 0 8px #c5c9ff;

      .ant-popover-inner-content {
        border: 2px solid #dfe1ff;
        box-sizing: content-box;
        height: 108px;
        padding: 6px 8px;
        width: 156px;
      }
    }
  }

  .layout-img-popover {
    height: 108px;
    width: 156px;
  }
}

// 颜色选择
.popover-color-set {
  width: 287px !important;

  .ant-popover-content {
    width: 277px;

    .ant-popover-inner {
      box-shadow: 0 0 8px #c5c9ff;

      .ant-popover-inner-content {
        border: 2px solid #dfe1ff;
        box-sizing: content-box;
        height: 25px;
        padding: 12px 16px;
        width: 245px;
      }
    }
  }
}
</style>
